Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: gelato and local signers #1346

Merged
merged 19 commits into from
Dec 30, 2024
Merged

feat: gelato and local signers #1346

merged 19 commits into from
Dec 30, 2024

Conversation

dohaki
Copy link
Contributor

@dohaki dohaki commented Dec 26, 2024

Closes ACX-3568, ACX-3569 and ACX-3570

This PR builds on top of #1345 and implements two relay strategies:

  • Gelato
  • Local Signers

The high-level lifecycle of a relay request is implemented as follows:

  1. User sends request via POST /relay
    • validates body
    • if valid publishes a message to a chain- and strategy-specific queue (currently we use QStash)
    • returns requestHash
  2. QStash processes messages by sending to POST /relay/jobs/process
    • makes sure to retry messages, takes care of parallelism, etc.
    • uses configured strategy to relay tx, i.e. via Gelato or local signers
  3. User can request status via GET /relay/status?requestHash
    • we can move this logic into POST /relay as well if the user wants a long-running atomic request

Copy link

vercel bot commented Dec 26, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
app-frontend-v3 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 30, 2024 0:12am
sepolia-frontend-v2 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 30, 2024 0:12am

Copy link

@bmzig bmzig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No major comments from me. I see there are still some TODOs, but not sure if you want to get them addressed in this PR or a follow-up.

@dohaki
Copy link
Contributor Author

dohaki commented Dec 27, 2024

No major comments from me. I see there are still some TODOs, but not sure if you want to get them addressed in this PR or a follow-up.

Thanks for reviewing! Yea the TODOs will be handled in follow up PRs. I opened separate tickets for them as well

@dohaki dohaki requested a review from mrice32 December 27, 2024 07:01
Base automatically changed from relay-base-handler to swap-endpoint December 28, 2024 07:50
const baseUrl = resolveVercelEndpoint(true);
const response = await queue.enqueueJSON({
retries: 3,
contentBasedDeduplication: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this solve nonce collision?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea that's the idea. by using a queue and setting parallelism to the number of signers we have, we should be able to mitigate nonce collisions on a single chain.

strategy: RelayStrategy;
}) {
const strategyName = strategy.strategyName;
const queue = getRelayRequestQueue(strategyName, request.chainId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is each queue/strategy using different EOAs? If not, how do we avoid nonce collisions between txns submitted within the same block between these queues?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it depends on the strategy. for example, if using Gelato, we don't need to handle nonce collisions because they take care of it. if using local signers, then we need to implement a mechanism/handler that's able to prevent nonce collisions.

break;
}

await new Promise((resolve) => setTimeout(resolve, 1_000));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: do you think there's value in setting the polling interval to the block time for the chain? or maybe make this an ENV?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm yea block time could make sense actually. a bit hesitant on using an env var though

data: encodedCalldata,
from: wallet.address,
};
const tx = await wallet.sendTransaction(txRequest);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make sense to simulate this tx first?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sendTransaction actually does an internal estimateGas call already if no gasLimit is provided


export function encodeCalldataForRelayRequest(request: RelayRequest) {
let encodedCalldata: string;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add a todo for transfer with auth?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep will do

try {
assert(request.query, RelayRequestStatusSchema);

const cachedRelayRequest = await getCachedRelayRequest(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we handle if a request hash is not found

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes good call!

deposit: depositTypedData.eip712,
permit: {
...permitTypedData.eip712,
message: stringifyBigNumProps(permitTypedData.eip712.message),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since stringifyBigNumProps runs recursively, can we call it once at the root of this object, just in case we might miss a value, or if we add fields in later PRs we might forget to also serialize that object correctly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep good point. I hoisted it up to api/swap/permit now

Copy link
Contributor

@gsteenkamp89 gsteenkamp89 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work! I only have a few questions, for my own understanding

@dohaki dohaki merged commit 3e650d2 into swap-endpoint Dec 30, 2024
9 checks passed
@dohaki dohaki deleted the gelato-and-local-signers branch December 30, 2024 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants